// 引入其他类
import Snake from './Snake';
import Food from './Food';
import ScorePanel from './ScorePanel';

// 游戏控制器  控制其他的所有类
class GameControl {
	snake: Snake; //蛇
	food: Food; //食物
	scorePanel: ScorePanel; //计分板
	direction: string = ''; //蛇的方向
	isLive = true; //是否或者

	constructor() {
		this.snake = new Snake();
		this.food = new Food();
		this.scorePanel = new ScorePanel(10, 2);
		this.init();
	}

	// 游戏的初始化方法  调用后游戏即开始
	init() {
		// 绑定键盘按下的时间
		document.addEventListener('keydown', this.keydownHandler.bind(this));
		// 调用run方法
		this.run();
	}

	// 创建一个键盘按下的响应函数
	keydownHandler(event: KeyboardEvent) {
		this.direction = event.key;
	}

	// 创建一个控制蛇移动的方法
	run() {
		/**
		 *  根据方向this.direction来改变蛇的位置
		 *      向上  top  减少
		 *      向下  top  增加
		 *      向左  left  减少
		 *      向右  left  增加
		 */
		// 获取蛇坐标
		let X = this.snake.X;
		let Y = this.snake.Y;

		// 根据按键方向来修改X、Y值
		switch (this.direction) {
			case 'ArrowUp':
			case 'Up':
				// 向上移动  top  减少
				Y -= 10;
				break;
			case 'ArrowDown':
			case 'Down':
				// 向下移动  top  增加
				Y += 10;
				break;
			case 'ArrowLeft':
			case 'Left':
				// 向左移动  left  减少
				X -= 10;
				break;
			case 'ArrowRight':
			case 'Right':
				// 向右移动  left  增加
				X += 10;
				break;
		}

		// 检查蛇是否吃到食物
		this.checkEat(X, Y);

		// 修改蛇的X、Y值
		try {
			this.snake.X = X;
			this.snake.Y = Y;
		} catch (error: any) {
			// 进入到catch  说明出现了异常，游戏结束，弹出一个提示信息
			alert(error.message);
			// 将isLive设置为false
			this.isLive = false;
		}

		// 开启一个定时调用
		this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30);
	}

	// 用来检测蛇是否吃到食物
	checkEat(X: number, Y: number) {
		if (X === this.food.X && Y === this.food.Y) {
			console.log('吃到了');
			// 食物位置发生变化
			this.food.change();
			// 分数增加
			this.scorePanel.addScore();
			// 蛇增加一节
			this.snake.addBody();
		}
	}
}

export default GameControl;
